package com.photovoltaic.neo4j.service;

import com.photovoltaic.neo4j.entity.Company;
import com.photovoltaic.neo4j.entity.Industry;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.neo4j.driver.*;
import org.neo4j.driver.types.Node;
import org.neo4j.driver.types.Path;
import org.neo4j.driver.types.Relationship;
import org.springframework.stereotype.Service;
import org.neo4j.driver.Record;

import java.util.*;
import java.util.stream.Collectors;

import static org.neo4j.driver.Values.parameters;

@Service
@RequiredArgsConstructor
@Slf4j
public class GraphAnalysisService {

    private final Driver neo4jDriver;

    // 实体查询
    public Map<String, Object> getEntityByName(String name, String entityType) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query = "MATCH (n:" + entityType + " {name: $name}) RETURN n";
                Result result = tx.run(query, parameters("name", name));
                
                if (!result.hasNext()) {
                    return Collections.emptyMap();
                }
                
                org.neo4j.driver.Record record = result.single();
                Node node = record.get("n").asNode();
                
                Map<String, Object> entityData = new HashMap<>();
                entityData.put("id", node.id());
                entityData.put("name", node.get("name").asString());
                entityData.put("properties", node.asMap());
                
                return entityData;
            });
        }
    }

    // 关系查询 - 直接供应商
    public Map<String, Object> getDirectSuppliers(String companyName) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query = "MATCH (a:Company {name: $name})-[:SUPPLIES]->(b:Company) RETURN b";
                Result result = tx.run(query, parameters("name", companyName));
                
                List<Map<String, Object>> suppliers = new ArrayList<>();
                while (result.hasNext()) {
                    org.neo4j.driver.Record record = result.next();
                    Node node = record.get("b").asNode();
                    
                    Map<String, Object> supplierData = new HashMap<>();
                    supplierData.put("id", node.id());
                    supplierData.put("name", node.get("name").asString());
                    supplierData.put("properties", node.asMap());
                    
                    suppliers.add(supplierData);
                }
                
                return Map.of("suppliers", suppliers);
            });
        }
    }

    // 路径查询 - 供应链路径
    public Map<String, Object> getSupplyChainPath(String sourceCompany, String targetCompany, int maxDepth) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query = "MATCH p = (a:Company {name: $source})-[:SUPPLIES*1.." + maxDepth + "]->(b:Company {name: $target}) RETURN p";
                Result result = tx.run(query, parameters("source", sourceCompany, "target", targetCompany));
                
                if (!result.hasNext()) {
                    return Collections.emptyMap();
                }
                
                List<Map<String, Object>> paths = new ArrayList<>();
                while (result.hasNext()) {
                    org.neo4j.driver.Record record = result.next();
                    Path path = record.get("p").asPath();
                    
                    Map<String, Object> pathData = new HashMap<>();
                    List<Map<String, Object>> nodes = new ArrayList<>();
                    List<Map<String, Object>> relationships = new ArrayList<>();
                    
                    for (Node node : path.nodes()) {
                        Map<String, Object> nodeData = new HashMap<>();
                        nodeData.put("id", node.id());
                        nodeData.put("name", node.get("name").asString());
                        nodeData.put("properties", node.asMap());
                        nodes.add(nodeData);
                    }
                    
                    for (Relationship rel : path.relationships()) {
                        Map<String, Object> relData = new HashMap<>();
                        relData.put("id", rel.id());
                        relData.put("type", rel.type());
                        relData.put("source", rel.startNodeId());
                        relData.put("target", rel.endNodeId());
                        relationships.add(relData);
                    }
                    
                    pathData.put("nodes", nodes);
                    pathData.put("relationships", relationships);
                    paths.add(pathData);
                }
                
                return paths.get(0);  // 返回第一个找到的路径
            });
        }
    }

    // 社区查询 - 供应商网络分析
    public List<Map<String, Object>> getSupplierCommunityAnalysis(String companyName) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query = "MATCH (a:Company {name: $name})-[:SUPPLIES]->(b:Company) " +
                               "RETURN b.province as province, b.establish_year as year, COUNT(b) as count";
                Result result = tx.run(query, parameters("name", companyName));
                
                List<Map<String, Object>> communityStats = new ArrayList<>();
                while (result.hasNext()) {
                    org.neo4j.driver.Record record = result.next();
                    Map<String, Object> stats = new HashMap<>();
                    stats.put("province", record.get("province").asString());
                    stats.put("year", record.get("year").asInt());
                    stats.put("count", record.get("count").asInt());
                    communityStats.add(stats);
                }
                
                return communityStats;
            });
        }
    }

    // 特征查询 - 多维度企业查询
    public Map<String, Object> getCompanyByFeatures(Map<String, Object> features) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                StringBuilder queryBuilder = new StringBuilder("MATCH (n:Company) WHERE ");
                Map<String, Object> params = new HashMap<>();
                
                for (Map.Entry<String, Object> entry : features.entrySet()) {
                    switch (entry.getKey()) {
                        case "province":
                            queryBuilder.append("n.province = $province AND ");
                            params.put("province", entry.getValue());
                            break;
                        case "isHighTech":
                            queryBuilder.append("n.is_high_tech = $isHighTech AND ");
                            params.put("isHighTech", entry.getValue());
                            break;
                        // 添加更多特征查询条件
                    }
                }
                
                queryBuilder.append("1=1 RETURN n");
                
                Result result = tx.run(queryBuilder.toString(), params);
                
                List<Map<String, Object>> companies = new ArrayList<>();
                while (result.hasNext()) {
                    org.neo4j.driver.Record record = result.next();
                    Node node = record.get("n").asNode();
                    
                    Map<String, Object> companyData = new HashMap<>();
                    companyData.put("id", node.id());
                    companyData.put("name", node.get("name").asString());
                    companyData.put("properties", node.asMap());
                    
                    companies.add(companyData);
                }
                
                return Map.of("companies", companies);
            });
        }
    }

    /**
     * 获取各省份企业统计数据
     * @param province 可选的省份筛选参数
     * @return 企业统计数据列表
     */
    public List<Map<String, Object>> getCompanyStatsByProvince(String province) {
        try (Session session = neo4jDriver.session()) {
            String cypher;
            if (province != null && !province.trim().isEmpty()) {
                // 如果提供了省份参数，只返回该省的数据
                cypher = "MATCH (c:Company) WHERE c.province = $province " +
                       "WITH c.province AS province, " +
                       "COUNT(c) AS companyCount, " +
                       "SUM(CASE WHEN c.isHighTech = true THEN 1 ELSE 0 END) AS highTechCount, " +
                       "AVG(toFloat(c.registeredCapital)) AS avgCapital, " +
                       "AVG(toInteger(c.employeeCount)) AS avgEmployeeCount, " +
                       "SUM(toInteger(c.employeeCount)) AS employeeCount, " +
                       "SUM(toFloat(c.registeredCapital)) AS registeredCapital " +
                       "RETURN province, companyCount, highTechCount, avgCapital, avgEmployeeCount, employeeCount, registeredCapital";
                
                return session.run(cypher, Map.of("province", province))
                        .list(record -> {
                            Map<String, Object> stats = new HashMap<>();
                            stats.put("province", record.get("province").asString());
                            stats.put("companyCount", record.get("companyCount").asInt());
                            stats.put("highTechCount", record.get("highTechCount").asInt());
                            
                            // 添加NULL值检查
                            Value avgCapitalValue = record.get("avgCapital");
                            if (!avgCapitalValue.isNull()) {
                                stats.put("avgCapital", avgCapitalValue.asDouble());
                            } else {
                                stats.put("avgCapital", 0.0);
                            }
                            
                            Value avgEmployeeValue = record.get("avgEmployeeCount");
                            if (!avgEmployeeValue.isNull()) {
                                stats.put("avgEmployeeCount", avgEmployeeValue.asDouble());
                            } else {
                                stats.put("avgEmployeeCount", 0.0);
                            }
                            
                            // 添加总人数和总注册资本
                            Value employeeCountValue = record.get("employeeCount");
                            if (!employeeCountValue.isNull()) {
                                stats.put("employeeCount", employeeCountValue.asInt());
                            } else {
                                stats.put("employeeCount", 0);
                            }
                            
                            Value registeredCapitalValue = record.get("registeredCapital");
                            if (!registeredCapitalValue.isNull()) {
                                stats.put("registeredCapital", registeredCapitalValue.asDouble());
                            } else {
                                stats.put("registeredCapital", 0.0);
                            }
                            
                            int companyCount = record.get("companyCount").asInt();
                            int highTechCount = record.get("highTechCount").asInt();
                            stats.put("highTechRatio", companyCount > 0 ? (double)highTechCount / companyCount : 0.0);
                            return stats;
                        });
            } else {
                // 原有的按省份分组统计逻辑
                cypher = "MATCH (c:Company) " +
                       "WITH c.province AS province, " +
                       "COUNT(c) AS companyCount, " +
                       "SUM(CASE WHEN c.isHighTech = true THEN 1 ELSE 0 END) AS highTechCount, " +
                       "AVG(toFloat(c.registeredCapital)) AS avgCapital, " +
                       "AVG(toInteger(c.employeeCount)) AS avgEmployeeCount, " +
                       "SUM(toInteger(c.employeeCount)) AS employeeCount, " +
                       "SUM(toFloat(c.registeredCapital)) AS registeredCapital " +
                       "WHERE province IS NOT NULL " +
                       "RETURN province, companyCount, highTechCount, avgCapital, avgEmployeeCount, employeeCount, registeredCapital " +
                       "ORDER BY companyCount DESC";
                
                return session.run(cypher)
                        .list(record -> {
                            Map<String, Object> stats = new HashMap<>();
                            stats.put("province", record.get("province").asString());
                            stats.put("companyCount", record.get("companyCount").asInt());
                            stats.put("highTechCount", record.get("highTechCount").asInt());
                            
                            // 添加NULL值检查
                            Value avgCapitalValue = record.get("avgCapital");
                            if (!avgCapitalValue.isNull()) {
                                stats.put("avgCapital", avgCapitalValue.asDouble());
                            } else {
                                stats.put("avgCapital", 0.0);
                            }
                            
                            Value avgEmployeeValue = record.get("avgEmployeeCount");
                            if (!avgEmployeeValue.isNull()) {
                                stats.put("avgEmployeeCount", avgEmployeeValue.asDouble());
                            } else {
                                stats.put("avgEmployeeCount", 0.0);
                            }
                            
                            // 添加总人数和总注册资本
                            Value employeeCountValue = record.get("employeeCount");
                            if (!employeeCountValue.isNull()) {
                                stats.put("employeeCount", employeeCountValue.asInt());
                            } else {
                                stats.put("employeeCount", 0);
                            }
                            
                            Value registeredCapitalValue = record.get("registeredCapital");
                            if (!registeredCapitalValue.isNull()) {
                                stats.put("registeredCapital", registeredCapitalValue.asDouble());
                            } else {
                                stats.put("registeredCapital", 0.0);
                            }
                            
                            int companyCount = record.get("companyCount").asInt();
                            int highTechCount = record.get("highTechCount").asInt();
                            stats.put("highTechRatio", companyCount > 0 ? (double)highTechCount / companyCount : 0.0);
                            return stats;
                        });
            }
        } catch (Exception e) {
            log.error("获取企业统计数据失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 获取指定行业各省份企业统计数据
     * @param industryName 行业名称
     * @return 企业统计数据列表
     */
    public List<Map<String, Object>> getCompanyStatsByIndustry(String industryName) {
        try (Session session = neo4jDriver.session()) {
            Map<String, Object> params = new HashMap<>();
            params.put("industryName", industryName);

            String cypher = "MATCH (c:Company)-[:BELONGS_TO]->(i:Industry {name: $industryName}) " +
                    "WITH c.province AS province, " +
                    "COUNT(c) AS companyCount, " +
                    "SUM(CASE WHEN c.is_high_tech = true THEN 1 ELSE 0 END) AS highTechCount, " +
                    "AVG(toFloat(c.registered_capital)) AS avgCapital, " +
                    "AVG(toInteger(c.employee_count)) AS avgEmployeeCount, " +
                    "SUM(toInteger(c.employee_count)) AS employeeCount, " +
                    "SUM(toFloat(c.registered_capital)) AS registeredCapital " +
                    "WHERE province IS NOT NULL " +
                    "RETURN province, companyCount, highTechCount, avgCapital, avgEmployeeCount, employeeCount, registeredCapital " +
                    "ORDER BY companyCount DESC";

            return session.run(cypher, params)
                    .list(record -> {
                        Map<String, Object> stats = new HashMap<>();
                        stats.put("province", record.get("province").asString());
                        stats.put("companyCount", record.get("companyCount").asInt());
                        stats.put("highTechCount", record.get("highTechCount").asInt());
                        
                        // 添加NULL值检查
                        Value avgCapitalValue = record.get("avgCapital");
                        if (!avgCapitalValue.isNull()) {
                            stats.put("avgCapital", avgCapitalValue.asDouble());
                        } else {
                            stats.put("avgCapital", 0.0);
                        }
                        
                        Value avgEmployeeValue = record.get("avgEmployeeCount");
                        if (!avgEmployeeValue.isNull()) {
                            stats.put("avgEmployeeCount", avgEmployeeValue.asDouble());
                        } else {
                            stats.put("avgEmployeeCount", 0.0);
                        }
                        
                        // 添加总人数和总注册资本
                        Value employeeCountValue = record.get("employeeCount");
                        if (!employeeCountValue.isNull()) {
                            stats.put("employeeCount", employeeCountValue.asInt());
                        } else {
                            stats.put("employeeCount", 0);
                        }
                        
                        Value registeredCapitalValue = record.get("registeredCapital");
                        if (!registeredCapitalValue.isNull()) {
                            stats.put("registeredCapital", registeredCapitalValue.asDouble());
                        } else {
                            stats.put("registeredCapital", 0.0);
                        }
                        
                        int companyCount = record.get("companyCount").asInt();
                        int highTechCount = record.get("highTechCount").asInt();
                        stats.put("highTechRatio", companyCount > 0 ? (double)highTechCount / companyCount : 0.0);
                        return stats;
                    });
        } catch (Exception e) {
            log.error("获取行业企业统计数据失败", e);
            return new ArrayList<>();
        }
    }

    // 在类中添加新的供应链分析方法
    public Map<String, Object> getSupplyChainAnalysis(String companyName, int depth) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                // 使用原生Cypher实现去重
                String query = "MATCH (c:Company {name: $companyName}) "
                             + "OPTIONAL MATCH path=(c)-[r:SUPPLIES*1.." + depth + "]->(related:Company) "
                             + "UNWIND relationships(path) AS rel "
                             + "WITH c, rel, related "
                             + "RETURN c AS rootNode, "
                             + "       collect(DISTINCT related) + [c] AS companies, "  // 包含所有相关公司
                             + "       collect(DISTINCT rel) AS relationships, "
                             + "       c {"
                             + "         .id, "
                             + "         .name, "
                             + "         .employee_count, "
                             + "         .company_scale, "
                             + "         .registered_capital, "
                             + "         .establish_year, "
                             + "         .province, "
                             + "         .risk_count, "
                             + "         .is_high_tech"
                             + "       } AS rootProps";

                Result result = tx.run(query, parameters("companyName", companyName));

                List<Map<String, Object>> nodes = new ArrayList<>();
                List<Map<String, Object>> links = new ArrayList<>();
                Set<Long> processedNodes = new HashSet<>();
                Set<Long> processedRels = new HashSet<>();

                while (result.hasNext()) {
                    Record record = result.next();
                    
                    // 处理节点
                    List<Node> nodeList = record.get("companies").asList(Value::asNode);
                    for (Node node : nodeList) {
                        if (node != null && processedNodes.add(node.id())) {
                            nodes.add(convertNodeToMap(node));
                        }
                    }

                    // 处理关系
                    List<Relationship> relList = record.get("relationships").asList(Value::asRelationship);
                    for (Relationship rel : relList) {
                        if (rel != null && processedRels.add(rel.id())) {
                            links.add(convertRelationshipToMap(rel));
                        }
                    }

                    // 确保根节点存在
                    Node rootNode = record.get("rootNode").asNode();
                    if (!processedNodes.contains(rootNode.id())) {
                        nodes.add(convertNodeToMap(rootNode));
                        processedNodes.add(rootNode.id());
                    }
                }

                return Map.of(
                    "nodes", nodes,
                    "links", links
                );
            });
        }
    }

    // 节点转换工具方法
    private Map<String, Object> convertNodeToMap(Node node) {
        Map<String, Object> nodeMap = new HashMap<>();
        nodeMap.put("id", String.valueOf(node.id()));
        nodeMap.put("name", node.containsKey("name") ? node.get("name").asString() : "未命名");
        
        // 员工数量处理 - 增强兼容性处理
        try {
            if (node.containsKey("employee_count")) {
                Value employeeValue = node.get("employee_count");
                if (!employeeValue.isNull()) {
                    if (employeeValue.type().name().equals("INTEGER")) {
                        nodeMap.put("employeeCount", employeeValue.asInt(0));
                    } else if (employeeValue.type().name().equals("STRING")) {
                        String empStr = employeeValue.asString();
                        try {
                            int empCount = Integer.parseInt(empStr);
                            nodeMap.put("employeeCount", empCount);
                        } catch (NumberFormatException e) {
                            nodeMap.put("employeeCount", 0);
                        }
                    } else {
                        nodeMap.put("employeeCount", 0);
                    }
                } else {
                    nodeMap.put("employeeCount", 0);
                }
            } else {
                nodeMap.put("employeeCount", 0);
            }
        } catch (Exception e) {
            log.warn("处理员工数量字段失败", e);
            nodeMap.put("employeeCount", 0);
        }
        
        nodeMap.put("companyScale", node.containsKey("company_scale") ? 
            node.get("company_scale").asString("未知") : "未知");
        
        nodeMap.put("registeredCapital", node.containsKey("registered_capital") ? 
            node.get("registered_capital").asDouble(0.0) : 0.0);
        
        // 成立年份处理 - 增强兼容性处理
        try {
            if (node.containsKey("establish_year")) {
                Value yearValue = node.get("establish_year");
                if (!yearValue.isNull()) {
                    if (yearValue.type().name().equals("INTEGER")) {
                        int year = yearValue.asInt(0);
                        nodeMap.put("establishYear", year > 0 ? year : 0);
                    } else if (yearValue.type().name().equals("STRING")) {
                        String yearStr = yearValue.asString();
                        try {
                            int year = Integer.parseInt(yearStr);
                            nodeMap.put("establishYear", year > 0 ? year : 0);
                        } catch (NumberFormatException e) {
                            nodeMap.put("establishYear", 0);
                        }
                    } else {
                        nodeMap.put("establishYear", 0);
                    }
                } else {
                    nodeMap.put("establishYear", 0);
                }
            } else {
                nodeMap.put("establishYear", 0);
            }
        } catch (Exception e) {
            log.warn("处理成立年份字段失败", e);
            nodeMap.put("establishYear", 0);
        }
        
        nodeMap.put("province", node.containsKey("province") ? 
            node.get("province").asString("未知") : "未知");
        
        // 风险数量处理 - 增强兼容性处理
        try {
            if (node.containsKey("risk_count")) {
                Value riskValue = node.get("risk_count");
                if (!riskValue.isNull()) {
                    if (riskValue.type().name().equals("INTEGER")) {
                        nodeMap.put("riskCount", riskValue.asInt(0));
                    } else if (riskValue.type().name().equals("STRING")) {
                        String riskStr = riskValue.asString();
                        try {
                            int riskCount = Integer.parseInt(riskStr);
                            nodeMap.put("riskCount", riskCount);
                        } catch (NumberFormatException e) {
                            nodeMap.put("riskCount", 0);
                        }
                    } else {
                        nodeMap.put("riskCount", 0);
                    }
                } else {
                    nodeMap.put("riskCount", 0);
                }
            } else {
                nodeMap.put("riskCount", 0);
            }
        } catch (Exception e) {
            log.warn("处理风险数量字段失败", e);
            nodeMap.put("riskCount", 0);
        }
        
        nodeMap.put("isHighTech", node.containsKey("is_high_tech") ? 
            node.get("is_high_tech").asBoolean(false) : false);

        return nodeMap;
    }

    // 关系转换工具方法
    private Map<String, Object> convertRelationshipToMap(Relationship rel) {
        Map<String, Object> relMap = new HashMap<>();
        relMap.put("id", rel.id());
        relMap.put("type", rel.type());  // 确保关系类型存在
        relMap.put("source", rel.startNodeId());
        relMap.put("target", rel.endNodeId());
        
        // 添加关系属性（如果有）
        rel.asMap().forEach((key, value) -> {
            if (!key.equals("type")) {  // 避免覆盖已有type字段
                relMap.put(key, value);
            }
        });
        
        return relMap;
    }

    // 企业风险分析方法
    public Map<String, Object> getCompanyRiskAnalysis(String industryName, Integer minRiskCount) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query = "MATCH (c:Company)-[:BELONGS_TO]->(i:Industry {name: $name}) " +
                               "WHERE c.risk_count >= $minRisk " +
                               "RETURN c.name as company, " +
                               "c.employee_count as employeeCount, " +
                               "c.company_scale as companyScale, " +
                               "c.registered_capital as registeredCapital, " +
                               "c.establish_year as establishYear, " +
                               "c.province as province, " +
                               "c.risk_count as riskCount, " +
                               "c.risk_types as types, " +
                               "c.is_high_tech as isHighTech";
                Result result = tx.run(query, parameters(
                    "name", industryName,
                    "minRisk", minRiskCount
                ));

                List<Map<String, Object>> riskyCompanies = new ArrayList<>();
                while (result.hasNext()) {
                    org.neo4j.driver.Record record = result.next();
                    Map<String, Object> companyRisk = new HashMap<>();
                    companyRisk.put("company", record.get("company").asString());
                    companyRisk.put("employeeCount", record.get("employeeCount").asInt(0));
                    companyRisk.put("companyScale", record.get("companyScale").asString("未知"));
                    companyRisk.put("registeredCapital", record.get("registeredCapital").asDouble(0.0));
                    companyRisk.put("establishYear", record.get("establishYear").asInt(0));
                    companyRisk.put("province", record.get("province").asString("未知"));
                    companyRisk.put("riskCount", record.get("riskCount").asInt());
                    companyRisk.put("isHighTech", record.get("isHighTech").asBoolean(false));
                    
                    // 添加NULL检查
                    Value typesValue = record.get("types");
                    if (!typesValue.isNull()) {
                        companyRisk.put("riskTypes", typesValue.asList(Value::asString));
                    } else {
                        companyRisk.put("riskTypes", Collections.emptyList());
                    }
                    
                    riskyCompanies.add(companyRisk);
                }

                return Map.of(
                    "industry", industryName,
                    "minRiskThreshold", minRiskCount,
                    "riskyCompanies", riskyCompanies
                );
            });
        }
    }

    // 添加行业分析方法
    public Map<String, Object> getIndustryAnalysis(String industryName) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query = "MATCH (i:Industry {name: $name})<-[:BELONGS_TO]-(c:Company) " +
                               "RETURN i.name as industry, " +
                               "COUNT(c) as companyCount, " +
                               "SUM(c.employee_count) as totalEmployees, " +
                               "AVG(c.registered_capital) as avgCapital, " +
                               "AVG(c.employee_count) as avgEmployees, " +
                               "COUNT(DISTINCT c.company_scale) as scaleCount, " +
                               "SUM(c.risk_count) as totalRiskCount, " +
                               "COUNT(CASE WHEN c.is_high_tech = true THEN 1 END) as highTechCount";
                Result result = tx.run(query, parameters("name", industryName));

                if (result.hasNext()) {
                    org.neo4j.driver.Record record = result.single();
                    return Map.of(
                        "industry", record.get("industry").asString(),
                        "companyCount", record.get("companyCount").asInt(),
                        "totalEmployees", record.get("totalEmployees").asInt(),
                        "avgCapital", record.get("avgCapital").asDouble(),
                        "avgEmployees", record.get("avgEmployees").asDouble(),
                        "scaleCount", record.get("scaleCount").asInt(),
                        "totalRiskCount", record.get("totalRiskCount").asInt(),
                        "highTechCount", record.get("highTechCount").asInt()
                    );
                }
                return Collections.emptyMap();
            });
        }
    }

    // 添加高新技术企业分析方法
    public Map<String, Object> getHighTechCompanyAnalysis(String industryName) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query = "MATCH (c:Company)-[:BELONGS_TO]->(i:Industry {name: $name}) " +
                               "WHERE c.is_high_tech = true " +
                               "RETURN i.name as industry, " +
                               "COUNT(c) as highTechCount, " +
                               "AVG(c.registered_capital) as avgCapital, " +
                               "SUM(c.employee_count) as totalEmployees";
                Result result = tx.run(query, parameters("name", industryName));

                if (result.hasNext()) {
                    org.neo4j.driver.Record record = result.single();
                    return Map.of(
                        "industry", record.get("industry").asString(),
                        "highTechCount", record.get("highTechCount").asInt(),
                        "avgRegisteredCapital", record.get("avgCapital").asDouble(),
                        "totalEmployees", record.get("totalEmployees").asInt()
                    );
                }
                return Collections.singletonMap("message", "No high-tech companies found");
            });
        }
    }

    // 添加公司搜索方法
    public List<Company> searchCompanies(String keyword) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query = "MATCH (c:Company) WHERE toLower(c.name) CONTAINS toLower($keyword) " +
                               "RETURN id(c) as id, c.name as name, " +  // 使用 elementId(c) 获取唯一标识
                               "c.employee_count as employeeCount, " +
                               "c.company_scale as companyScale, " +
                               "c.registered_capital as registeredCapital, " +
                               "c.establish_year as establishYear, " +
                               "c.province as province, " +
                               "c.risk_count as riskCount, " +
                               "c.risk_types as riskTypes, " +
                               "c.is_high_tech as isHighTech " +
                               "LIMIT 10";
                Result result = tx.run(query, parameters("keyword", keyword));
                
                List<Company> companies = new ArrayList<>();
                while (result.hasNext()) {
                    Record record = result.next();
                    Company company = new Company();
                    // 使用 elementId(c) 作为 id
                    company.setId(record.get("id").toString());  // 将 id 作为字符串处理
                    company.setName(record.get("name").asString());
                    company.setEmployeeCount(record.get("employeeCount").asInt(0));
                    company.setCompanyScale(record.get("companyScale").asString("未知"));
                    company.setRegisteredCapital(record.get("registeredCapital").asDouble(0.0));
                    company.setEstablishYear(record.get("establishYear").asInt(0));
                    company.setProvince(record.get("province").asString("未知"));
                    company.setRiskCount(record.get("riskCount").asInt());
                    // 处理 NULL riskTypes
                    Value riskTypesValue = record.get("riskTypes");
                    company.setRiskTypes(riskTypesValue.isNull() ? Collections.emptyList() : riskTypesValue.asList(Value::asString));
                    company.setHighTech(record.get("isHighTech").asBoolean(false));
                    companies.add(company);
                }
                return companies;
            });
        }
    }

    public Map<String, Object> getIndustryCompanies(String industryName) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String cypher = "MATCH (c:Company)-[r:BELONGS_TO]->(i:Industry) "
                              + "WHERE i.name = $industryName "
                              + "OPTIONAL MATCH (c)-[r2:SUPPLIES]->(related:Company) "
                              + "RETURN c{"
                              + "  .id,"
                              + "  .name,"
                              + "  .employeeCount,"
                              + "  .companyScale,"
                              + "  .registeredCapital,"
                              + "  .establishYear,"
                              + "  .province,"
                              + "  .riskCount,"
                              + "  .isHighTech"
                              + "} as node, "
                              + "COLLECT(DISTINCT r2) as relationships";

                Map<String, Object> params = Map.of("industryName", industryName);
                
                Result result = tx.run(cypher, params);
                
                List<Map<String, Object>> nodes = new ArrayList<>();
                List<Map<String, Object>> links = new ArrayList<>();
                
                while (result.hasNext()) {
                    Record record = result.next();
                    
                    Map<String, Object> node = record.get("node").asMap();
                    List<Relationship> rels = record.get("relationships").asList(Value::asRelationship);
                    
                    List<Map<String, Object>> linksForNode = rels.stream()
                        .filter(Objects::nonNull)
                        .map(rel -> {
                            Map<String, Object> link = new HashMap<>();
                            link.put("source", rel.startNodeId());
                            link.put("target", rel.endNodeId());
                            link.put("type", rel.type());
                            return link;
                        })
                        .collect(Collectors.toList());
                    
                    links.addAll(linksForNode);
                    nodes.add(node);
                }
                
                return Map.of(
                    "nodes", nodes,
                    "links", links
                );
            });
        }
    }

    /**
     * 搜索产品
     * @param keyword 关键词
     * @return 产品列表
     * @deprecated 请使用 ProductService.searchProducts 替代
     */
    @Deprecated
    public List<Map<String, Object>> searchProducts(String keyword) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query;
                Result result;
                
                // 如果关键词为空，则返回所有产品（限制数量）
                if (keyword == null || keyword.trim().isEmpty()) {
                    query = "MATCH (p:Product) " +
                            "RETURN id(p) as id, p.name as name, " +
                            "p.description as description, " +
                            "labels(p) as labels " +
                            "ORDER BY p.name " +
                            "LIMIT 10";
                    result = tx.run(query);
                } else {
                    query = "MATCH (p:Product) WHERE toLower(p.name) CONTAINS toLower($keyword) " +
                            "RETURN id(p) as id, p.name as name, " +
                            "p.description as description, " +
                            "labels(p) as labels " +
                            "LIMIT 10";
                    result = tx.run(query, parameters("keyword", keyword));
                }
                
                List<Map<String, Object>> products = new ArrayList<>();
                while (result.hasNext()) {
                    Record record = result.next();
                    Map<String, Object> product = new HashMap<>();
                    product.put("id", record.get("id").toString());
                    product.put("name", record.get("name").asString());
                    
                    // 处理可能为空的字段
                    Value descValue = record.get("description");
                    if (!descValue.isNull()) {
                        product.put("description", descValue.asString());
                    } else {
                        product.put("description", "");
                    }
                    
                    // 获取节点标签
                    List<String> labels = record.get("labels").asList(Value::asString);
                    product.put("type", labels.contains("Product") ? "Product" : labels.get(0));
                    
                    products.add(product);
                }
                return products;
            });
        }
    }

    /**
     * 获取产品上下游关系
     * @param productName 产品名称
     * @param depth 查询深度
     * @param direction 查询方向 (upstream/downstream/both)
     * @return 产品上下游关系数据
     * @deprecated 请使用 ProductService.getProductChain 替代
     */
    @Deprecated
    public Map<String, Object> getProductChain(String productName, Integer depth, String direction) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                // 如果产品名称为空，则返回默认数据集
                if (productName == null || productName.trim().isEmpty()) {
                    // 查询几个主要产品的关系
                    String defaultQuery = "MATCH (p:Product) " +
                                         "WITH p LIMIT 5 " +
                                         "OPTIONAL MATCH (p)-[r:UPSTREAM_OF]-(related) " +
                                         "RETURN collect(distinct p) as nodes, collect(distinct r) as rels";
                    
                    Result defaultResult = tx.run(defaultQuery);
                    if (defaultResult.hasNext()) {
                        Record record = defaultResult.next();
                        
                        List<Node> nodeList = record.get("nodes").asList(Value::asNode);
                        List<Relationship> relList = record.get("rels").asList(Value::asRelationship);
                        
                        List<Map<String, Object>> nodes = new ArrayList<>();
                        List<Map<String, Object>> relationships = new ArrayList<>();
                        
                        // 处理节点
                        for (Node node : nodeList) {
                            Map<String, Object> nodeMap = new HashMap<>();
                            nodeMap.put("id", String.valueOf(node.id()));
                            nodeMap.put("name", node.containsKey("name") ? node.get("name").asString() : "未命名");
                            
                            // 获取节点类型
                            List<String> labels = new ArrayList<>();
                            node.labels().forEach(labels::add);
                            String nodeType = labels.contains("Product") ? "Product" : 
                                            (labels.contains("Material") ? "Material" : labels.get(0));
                            nodeMap.put("type", nodeType);
                            
                            // 获取描述
                            if (node.containsKey("description")) {
                                nodeMap.put("description", node.get("description").asString());
                            } else {
                                nodeMap.put("description", "");
                            }
                            
                            // 其他属性
                            Map<String, Object> properties = new HashMap<>(node.asMap());
                            properties.remove("name");
                            properties.remove("description");
                            nodeMap.put("properties", properties);
                            
                            nodes.add(nodeMap);
                        }
                        
                        // 处理关系
                        for (Relationship rel : relList) {
                            Map<String, Object> relMap = new HashMap<>();
                            relMap.put("id", String.valueOf(rel.id()));
                            relMap.put("source", String.valueOf(rel.startNodeId()));
                            relMap.put("target", String.valueOf(rel.endNodeId()));
                            relMap.put("type", rel.type());
                            
                            // 关系属性
                            Map<String, Object> properties = new HashMap<>(rel.asMap());
                            relMap.put("properties", properties);
                            
                            relationships.add(relMap);
                        }
                        
                        return Map.of(
                            "nodes", nodes,
                            "relationships", relationships
                        );
                    }
                }
                
                // 以下是原来的代码，处理有产品名称的情况
                // 构建查询语句，根据方向选择不同的关系模式
                StringBuilder queryBuilder = new StringBuilder();
                queryBuilder.append("MATCH (p:Product {name: $productName}) ");
                
                // 根据方向构建不同的查询路径
                if ("upstream".equals(direction)) {
                    // 上游：查找是该产品上游的产品/材料
                    // A UPSTREAM_OF B 表示A是B的上游
                    queryBuilder.append("OPTIONAL MATCH path = (material)-[:UPSTREAM_OF*1..").append(depth).append("]->(p) ");
                } else if ("downstream".equals(direction)) {
                    // 下游：查找该产品是其上游的产品/材料
                    // A UPSTREAM_OF B 表示A是B的上游，所以p UPSTREAM_OF product表示p是product的上游
                    queryBuilder.append("OPTIONAL MATCH path = (p)-[:UPSTREAM_OF*1..").append(depth).append("]->(product) ");
                } else {
                    // 默认双向：同时查找上下游
                    queryBuilder.append("OPTIONAL MATCH path1 = (material)-[:UPSTREAM_OF*1..").append(depth).append("]->(p) ");
                    queryBuilder.append("OPTIONAL MATCH path2 = (p)-[:UPSTREAM_OF*1..").append(depth).append("]->(product) ");
                    queryBuilder.append("WITH p, path1, path2 ");
                    queryBuilder.append("WITH p, [path1, path2] AS paths ");
                    queryBuilder.append("UNWIND paths AS path ");
                }
                
                // 提取节点和关系
                if ("both".equals(direction)) {
                    queryBuilder.append("WITH p, path WHERE path IS NOT NULL ");
                } else {
                    queryBuilder.append("WITH p, path ");
                }
                
                queryBuilder.append("UNWIND nodes(path) AS node ");
                queryBuilder.append("UNWIND relationships(path) AS rel ");
                queryBuilder.append("WITH COLLECT(DISTINCT node) AS nodes, COLLECT(DISTINCT rel) AS rels, p ");
                queryBuilder.append("RETURN nodes + p AS allNodes, rels AS allRelationships");
                
                Result result = tx.run(queryBuilder.toString(), parameters("productName", productName));
                
                List<Map<String, Object>> nodes = new ArrayList<>();
                List<Map<String, Object>> relationships = new ArrayList<>();
                Set<String> processedNodeIds = new HashSet<>();
                Set<String> processedRelIds = new HashSet<>();
                
                if (result.hasNext()) {
                    Record record = result.next();
                    
                    // 处理节点
                    List<Node> nodeList = record.get("allNodes").asList(Value::asNode);
                    for (Node node : nodeList) {
                        String nodeId = String.valueOf(node.id());
                        if (!processedNodeIds.contains(nodeId)) {
                            Map<String, Object> nodeMap = new HashMap<>();
                            nodeMap.put("id", nodeId);
                            nodeMap.put("name", node.containsKey("name") ? node.get("name").asString() : "未命名");
                            
                            // 获取节点类型
                            List<String> labels = new ArrayList<>();
                            node.labels().forEach(labels::add);
                            String nodeType = labels.contains("Product") ? "Product" : 
                                             (labels.contains("Material") ? "Material" : labels.get(0));
                            nodeMap.put("type", nodeType);
                            
                            // 获取描述
                            if (node.containsKey("description")) {
                                nodeMap.put("description", node.get("description").asString());
                            } else {
                                nodeMap.put("description", "");
                            }
                            
                            // 其他属性
                            Map<String, Object> properties = new HashMap<>(node.asMap());
                            properties.remove("name");
                            properties.remove("description");
                            nodeMap.put("properties", properties);
                            
                            nodes.add(nodeMap);
                            processedNodeIds.add(nodeId);
                        }
                    }
                    
                    // 处理关系
                    List<Relationship> relList = record.get("allRelationships").asList(Value::asRelationship);
                    for (Relationship rel : relList) {
                        String relId = String.valueOf(rel.id());
                        if (!processedRelIds.contains(relId)) {
                            Map<String, Object> relMap = new HashMap<>();
                            relMap.put("id", relId);
                            relMap.put("source", String.valueOf(rel.startNodeId()));
                            relMap.put("target", String.valueOf(rel.endNodeId()));
                            relMap.put("type", rel.type());
                            
                            // 关系属性
                            Map<String, Object> properties = new HashMap<>(rel.asMap());
                            relMap.put("properties", properties);
                            
                            relationships.add(relMap);
                            processedRelIds.add(relId);
                        }
                    }
                }
                
                return Map.of(
                    "nodes", nodes,
                    "relationships", relationships
                );
            });
        }
    }

    /**
     * 行业企业综合分析
     * 整合行业内企业统计分析、高新技术企业与普通企业对比、企业创新能力评估
     * 
     * @param industryName 行业名称
     * @return 行业企业综合分析数据
     */
    public Map<String, Object> getIndustryComprehensiveAnalysis(String industryName) {
        try (Session session = neo4jDriver.session()) {
            Map<String, Object> result = new HashMap<>();
            
            // 1. 行业企业总体统计分析
            result.put("industryStatistics", session.readTransaction(tx -> {
                String query = "MATCH (c:Company)-[:BELONGS_TO]->(i:Industry {name: $name}) " +
                               "WITH i, count(c) AS company_count, " +
                               "sum(CASE WHEN c.employee_count IS NOT NULL THEN c.employee_count ELSE 0 END) AS total_employees, " +
                               "avg(CASE WHEN c.registered_capital IS NOT NULL THEN c.registered_capital ELSE 0 END) AS avg_capital, " +
                               "count(CASE WHEN c.is_high_tech = true THEN 1 END) AS hightech_count " +
                               "RETURN i.name AS industry, " +
                               "company_count, " +
                               "total_employees, " +
                               "avg_capital, " +
                               "hightech_count, " +
                               "CASE WHEN company_count > 0 THEN toFloat(hightech_count)/company_count ELSE 0 END AS hightech_ratio";
                
                Result queryResult = tx.run(query, parameters("name", industryName));
                
                if (queryResult.hasNext()) {
                    Record record = queryResult.single();
                    Map<String, Object> stats = new HashMap<>();
                    stats.put("industry", record.get("industry").asString(industryName));
                    stats.put("companyCount", record.get("company_count").asInt(0));
                    stats.put("totalEmployees", record.get("total_employees").asInt(0));
                    stats.put("avgCapital", record.get("avg_capital").asDouble(0.0));
                    stats.put("hightechCount", record.get("hightech_count").asInt(0));
                    stats.put("hightechRatio", record.get("hightech_ratio").asDouble(0.0));
                    return stats;
                }
                
                // 如果没有数据，返回空的统计结果
                Map<String, Object> emptyStats = new HashMap<>();
                emptyStats.put("industry", industryName);
                emptyStats.put("companyCount", 0);
                emptyStats.put("totalEmployees", 0);
                emptyStats.put("avgCapital", 0.0);
                emptyStats.put("hightechCount", 0);
                emptyStats.put("hightechRatio", 0.0);
                return emptyStats;
            }));
            
            // 2. 企业规模分布
            result.put("companySizeDistribution", session.readTransaction(tx -> {
                String query = "MATCH (c:Company)-[:BELONGS_TO]->(i:Industry {name: $name}) " +
                               "WITH i, c.company_scale AS size, count(c) AS count " +
                               "RETURN size, count " +
                               "ORDER BY count DESC";
                
                Result queryResult = tx.run(query, parameters("name", industryName));
                
                List<Map<String, Object>> distribution = new ArrayList<>();
                while (queryResult.hasNext()) {
                    Record record = queryResult.next();
                    Map<String, Object> item = new HashMap<>();
                    // 处理可能为空的情况
                    Value sizeValue = record.get("size");
                    item.put("size", sizeValue.isNull() ? "未知" : sizeValue.asString("未知"));
                    item.put("count", record.get("count").asInt(0));
                    distribution.add(item);
                }
                
                // 如果没有数据，返回空列表
                return distribution;
            }));
            
            // 3. 高新技术企业与普通企业对比
            result.put("hightechComparison", session.readTransaction(tx -> {
                String query = "MATCH (c:Company)-[:BELONGS_TO]->(i:Industry {name: $name}) " +
                               "WITH i, c.is_high_tech AS isHighTech, " +
                               "avg(CASE WHEN c.employee_count IS NOT NULL THEN c.employee_count ELSE 0 END) AS avg_employees, " +
                               "avg(CASE WHEN c.registered_capital IS NOT NULL THEN c.registered_capital ELSE 0 END) AS avg_capital, " +
                               "avg(CASE WHEN c.patent_count IS NOT NULL THEN c.patent_count ELSE 0 END) AS avg_patents, " +
                               "count(c) AS company_count " +
                               "RETURN isHighTech, " +
                               "avg_employees, " +
                               "avg_capital, " +
                               "avg_patents, " +
                               "company_count";
                
                Result queryResult = tx.run(query, parameters("name", industryName));
                
                List<Map<String, Object>> comparison = new ArrayList<>();
                while (queryResult.hasNext()) {
                    Record record = queryResult.next();
                    Map<String, Object> item = new HashMap<>();
                    
                    // 处理可能为空的情况
                    Value highTechValue = record.get("isHighTech");
                    item.put("isHighTech", highTechValue.isNull() ? false : highTechValue.asBoolean(false));
                    item.put("avgEmployees", record.get("avg_employees").asDouble(0.0));
                    item.put("avgCapital", record.get("avg_capital").asDouble(0.0));
                    item.put("avgPatents", record.get("avg_patents").asDouble(0.0));
                    item.put("companyCount", record.get("company_count").asInt(0));
                    
                    comparison.add(item);
                }
                
                // 如果没有数据，返回空列表
                return comparison;
            }));
            
            // 4. 企业创新能力分析 - 专利分布TOP20
            result.put("patentDistribution", session.readTransaction(tx -> {
                String query = "MATCH (c:Company)-[:BELONGS_TO]->(i:Industry {name: $name}) " +
                               "WHERE c.patent_count IS NOT NULL AND c.patent_count > 0 " +
                               "RETURN c.name AS company, c.patent_count AS patents " +
                               "ORDER BY patents DESC " +
                               "LIMIT 20";
                
                Result queryResult = tx.run(query, parameters("name", industryName));
                
                List<Map<String, Object>> patentList = new ArrayList<>();
                while (queryResult.hasNext()) {
                    Record record = queryResult.next();
                    Map<String, Object> item = new HashMap<>();
                    item.put("company", record.get("company").asString());
                    item.put("patents", record.get("patents").asInt(0));
                    patentList.add(item);
                }
                
                // 如果没有数据，返回空列表
                return patentList;
            }));
            
            // 5. 创新效率分析 - 专利数/员工数 TOP20
            result.put("innovationEfficiency", session.readTransaction(tx -> {
                String query = "MATCH (c:Company)-[:BELONGS_TO]->(i:Industry {name: $name}) " +
                               "WHERE c.employee_count IS NOT NULL AND c.employee_count > 0 " +
                               "AND c.patent_count IS NOT NULL AND c.patent_count > 0 " +
                               "WITH c, c.patent_count AS patents, c.employee_count AS employees, " +
                               "toFloat(c.patent_count)/c.employee_count AS efficiency " +
                               "RETURN c.name AS company, " +
                               "patents, " +
                               "employees, " +
                               "efficiency " +
                               "ORDER BY efficiency DESC " +
                               "LIMIT 20";
                
                Result queryResult = tx.run(query, parameters("name", industryName));
                
                List<Map<String, Object>> efficiencyList = new ArrayList<>();
                while (queryResult.hasNext()) {
                    Record record = queryResult.next();
                    Map<String, Object> item = new HashMap<>();
                    item.put("company", record.get("company").asString());
                    item.put("patents", record.get("patents").asInt(0));
                    item.put("employees", record.get("employees").asInt(0));
                    item.put("efficiency", record.get("efficiency").asDouble(0.0));
                    efficiencyList.add(item);
                }
                
                // 如果没有数据，返回空列表
                return efficiencyList;
            }));
            
            // 返回完整的分析结果
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            return Map.of(
                "error", "分析行业企业数据失败: " + e.getMessage(),
                "industryStatistics", Map.of(
                    "industry", industryName,
                    "companyCount", 0,
                    "totalEmployees", 0,
                    "avgCapital", 0.0,
                    "hightechCount", 0,
                    "hightechRatio", 0.0
                ),
                "companySizeDistribution", Collections.emptyList(),
                "hightechComparison", Collections.emptyList(),
                "patentDistribution", Collections.emptyList(),
                "innovationEfficiency", Collections.emptyList()
            );
        }
    }

    /**
     * 根据名称模糊查询行业列表
     * @param keyword 关键词
     * @return 行业列表
     */
    public List<Industry> searchIndustries(String keyword) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                String query = "MATCH (i:Industry) WHERE toLower(i.name) CONTAINS toLower($keyword) RETURN i";
                Result result = tx.run(query, parameters("keyword", keyword));
                
                List<Industry> industries = new ArrayList<>();
                while (result.hasNext()) {
                    Record record = result.next();
                    Industry industry = new Industry();
                    industry.setName(record.get("i").asNode().get("name").asString());
                    industries.add(industry);
                }
                return industries;
            });
        }
    }

    // 新增：获取关键材料分析
    public Map<String, Object> getKeyMaterials() {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                // 1. 获取所有产品和原材料节点，以及它们之间的关系
                String graphQuery = "MATCH (n) WHERE n:Product OR n:Material "
                                  + "OPTIONAL MATCH (n)-[r:UPSTREAM_OF]->(m) WHERE m:Product OR m:Material "
                                  + "RETURN collect(DISTINCT n) as nodes, collect(DISTINCT r) as relationships";
                Result graphResult = tx.run(graphQuery);
                Record graphRecord = graphResult.single();
    
                List<Node> allNodes = graphRecord.get("nodes").asList(Value::asNode);
                List<Relationship> allRelationships = graphRecord.get("relationships").asList(Value::asRelationship);
    
                // 转换节点和关系为Map列表
                List<Map<String, Object>> nodesMap = allNodes.stream()
                        .map(this::convertNodeToMap) // 复用现有的转换方法
                        .collect(Collectors.toList());
                
                List<Map<String, Object>> relationshipsMap = allRelationships.stream()
                        .map(this::convertRelationshipToMap) // 复用现有的转换方法
                        .collect(Collectors.toList());
    
                // 2. 计算每个产品节点的连接度
                String connectionQuery = "MATCH (p:Product) "
                                     + "MATCH (p)-[:UPSTREAM_OF]-(related) "
                                     + "WITH p, count(related) AS connection_count "
                                     + "WHERE connection_count > 1 "
                                     + "RETURN p.name AS name, id(p) AS id, connection_count "
                                     + "ORDER BY connection_count DESC "
                                     + "LIMIT 10";
                Result connectionResult = tx.run(connectionQuery);
                List<Map<String, Object>> keyMaterialsByConnection = connectionResult.list(record -> 
                    Map.of("name", record.get("name").asString(),
                           "id", record.get("id").asLong(),
                           "connection_count", record.get("connection_count").asInt()));
    
                // 3. 识别同时是上游和下游的中介节点
                String intermediaryQuery = "MATCH (p:Product) "
                                       + "MATCH (upstream:Product)-[:UPSTREAM_OF]->(p) "
                                       + "MATCH (p)-[:UPSTREAM_OF]->(downstream:Product) "
                                       + "WITH p, count(DISTINCT upstream) AS upstream_count, "
                                       + "     count(DISTINCT downstream) AS downstream_count "
                                       + "WHERE upstream_count > 0 AND downstream_count > 0 "
                                       + "RETURN p.name AS name, id(p) AS id, "
                                       + "       upstream_count, "
                                       + "       downstream_count, "
                                       + "       upstream_count + downstream_count AS total_connections "
                                       + "ORDER BY total_connections DESC";
                Result intermediaryResult = tx.run(intermediaryQuery);
                List<Map<String, Object>> keyMaterialsByIntermediary = intermediaryResult.list(record -> {
                    int upstreamCount = record.get("upstream_count").asInt();
                    int downstreamCount = record.get("downstream_count").asInt();
                    return Map.of("name", record.get("name").asString(),
                                  "id", record.get("id").asLong(), 
                                  "upstream_count", upstreamCount,
                                  "downstream_count", downstreamCount,
                                  "total_connections", record.get("total_connections").asInt());
                });
    
                // 组合结果
                Map<String, Object> finalResult = new HashMap<>();
                finalResult.put("nodes", nodesMap);
                finalResult.put("relationships", relationshipsMap);
                finalResult.put("keyMaterialsByConnection", keyMaterialsByConnection);
                finalResult.put("keyMaterialsByIntermediary", keyMaterialsByIntermediary);
    
                return finalResult;
            });
        }
    }

    /**
     * 分析供应链脆弱性
     * 评估关键材料的供应稳定性，识别可能导致供应链中断的脆弱点
     * @param materials 要分析的关键材料列表
     * @return 供应链脆弱性分析结果
     */
    public List<Map<String, Object>> getSupplyChainVulnerability(List<String> materials) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                List<Map<String, Object>> results = new ArrayList<>();
                
                // 如果没有指定材料，则查询关键材料
                List<String> materialsList = materials;
                if (materialsList == null || materialsList.isEmpty()) {
                    // 获取关键材料列表(复用关键材料识别功能)
                    String keyMaterialsQuery = "MATCH (p:Product) "
                                             + "MATCH (p)-[:UPSTREAM_OF]-(related) "
                                             + "WITH p, count(related) AS connection_count "
                                             + "WHERE connection_count > 1 "
                                             + "RETURN p.name AS name "
                                             + "ORDER BY connection_count DESC "
                                             + "LIMIT 10";
                    
                    Result keyMaterialsResult = tx.run(keyMaterialsQuery);
                    List<String> keyMaterials = new ArrayList<>();
                    while (keyMaterialsResult.hasNext()) {
                        Record record = keyMaterialsResult.next();
                        keyMaterials.add(record.get("name").asString());
                    }
                    
                    if (keyMaterials.isEmpty()) {
                        return results; // 如果没有关键材料，则直接返回空结果
                    }
                    
                    materialsList = keyMaterials;
                }
                
                // 对每个关键材料分析其生产企业的情况
                for (String material : materialsList) {

                    // 1. 查询生产该材料的企业数量
                    String producerCountQuery = "MATCH (p:Product {name: $material}) "
                                              + "MATCH (c:Company)-[:PRODUCES]->(p) "
                                              + "RETURN count(c) AS producer_count";
                    
                    Result producerCountResult = tx.run(producerCountQuery, parameters("material", material));
                    int producerCount = 0;
                    if (producerCountResult.hasNext()) {
                        Record record = producerCountResult.next();
                        producerCount = record.get("producer_count").asInt();
                    }
                    
                    // 2. 查询生产该材料的高风险企业数量
                    String highRiskProducerQuery = "MATCH (p:Product {name: $material}) "
                                               + "MATCH (c:Company)-[:PRODUCES]->(p) "
                                               + "WHERE c.risk_count > 50 OR c.riskCount > 50 "
                                               + "RETURN count(c) AS high_risk_producer_count";
                    
                    Result highRiskProducerResult = tx.run(highRiskProducerQuery, parameters("material", material));
                    int highRiskProducerCount = 0;
                    if (highRiskProducerResult.hasNext()) {
                        Record record = highRiskProducerResult.next();
                        highRiskProducerCount = record.get("high_risk_producer_count").asInt();
                    }
                    
                    // 计算风险比例
                    double riskRatio = producerCount > 0 ? (double) highRiskProducerCount / producerCount : 0;
                    
                    // 构建结果
                    Map<String, Object> materialVulnerability = new HashMap<>();
                    materialVulnerability.put("productName", material);
                    materialVulnerability.put("producerCount", producerCount);
                    materialVulnerability.put("highRiskProducerCount", highRiskProducerCount);
                    materialVulnerability.put("riskRatio", riskRatio);
                    
                    results.add(materialVulnerability);
                }
                
                // 按风险比例排序
                results.sort((a, b) -> {
                    Double riskRatioA = (Double) a.get("riskRatio");
                    Double riskRatioB = (Double) b.get("riskRatio");
                    return riskRatioB.compareTo(riskRatioA); // 降序排列
                });
                
                return results;
            });
        }
    }

    /**
     * 分析替代路径
     * 分析某一材料缺失或成本上升时的潜在替代方案
     * @param materialName 要分析替代方案的材料名称
     * @param minSimilarity 最小相似度（0-1之间的小数）
     * @return 替代路径分析结果
     */
    public Map<String, Object> getSubstituteAnalysis(String materialName, Double minSimilarity) {
        try (Session session = neo4jDriver.session()) {
            return session.readTransaction(tx -> {
                Map<String, Object> results = new HashMap<>();
                
                // 1. 识别具有相似上游/下游关系的材料（潜在替代品）
                String substituteQuery = "MATCH (target:Product {name: $materialName}) " +
                        "MATCH (target)-[:UPSTREAM_OF]->(downstream:Product) " +
                        "WITH target, collect(downstream) AS target_downstream " +
                        "MATCH (other:Product) " +
                        "WHERE other <> target " +
                        "MATCH (other)-[:UPSTREAM_OF]->(downstream2:Product) " +
                        "WITH target, other, target_downstream, collect(downstream2) AS other_downstream " +
                        "WITH target, other, " +
                        "     [x IN target_downstream WHERE x IN other_downstream] AS common_downstream, " +
                        "     size(target_downstream) AS target_count, " +
                        "     size(other_downstream) AS other_count " +
                        "WITH target, other, " +
                        "     size(common_downstream) AS common_count, " +
                        "     target_count, other_count, " +
                        "     common_downstream " +
                        "WHERE common_count > 0  " +
                        "RETURN target.name AS target_material, " +
                        "       other.name AS potential_substitute, " +
                        "       common_count AS common_connections, " +
                        "       toFloat(common_count) / target_count AS similarity_score, " +
                        "       [x in common_downstream | x.name] AS common_products " +
                        "ORDER BY similarity_score DESC";
                
                Result substituteResult = tx.run(substituteQuery, 
                        parameters("materialName", materialName, "minSimilarity", minSimilarity));
                
                List<Map<String, Object>> substitutes = new ArrayList<>();
                while (substituteResult.hasNext()) {
                    Record record = substituteResult.next();
                    Map<String, Object> substitute = new HashMap<>();
                    substitute.put("targetMaterial", record.get("target_material").asString());
                    substitute.put("potentialSubstitute", record.get("potential_substitute").asString());
                    substitute.put("commonConnections", record.get("common_connections").asInt());
                    substitute.put("similarityScore", record.get("similarity_score").asDouble());
                    substitute.put("commonProducts", record.get("common_products").asList(Value::asString));
                    
                    substitutes.add(substitute);
                }
                
                // 2. 获取替代材料生产企业情况
                List<Map<String, Object>> substitutesWithSuppliers = new ArrayList<>();
                for (Map<String, Object> substitute : substitutes) {
                    String substituteName = (String) substitute.get("potentialSubstitute");
                    
                    // 查询生产该替代材料的企业
                    String supplierQuery = "MATCH (p:Product {name: $substituteName}) " +
                            "MATCH (c:Company)-[:PRODUCES]->(p) " +
                            "RETURN c.name AS company_name, " +
                            "       c.province AS province, " +
                            "       c.registeredCapital AS capital, " +
                            "       c.isHighTech AS is_high_tech " +
                            "LIMIT 5";
                    
                    Result supplierResult = tx.run(supplierQuery, parameters("substituteName", substituteName));
                    List<Map<String, Object>> suppliers = new ArrayList<>();
                    while (supplierResult.hasNext()) {
                        Record record = supplierResult.next();
                        Map<String, Object> supplier = new HashMap<>();
                        supplier.put("name", record.get("company_name").asString());
                        
                        if (!record.get("province").isNull()) {
                            supplier.put("province", record.get("province").asString());
                        }
                        
                        if (!record.get("capital").isNull()) {
                            supplier.put("capital", record.get("capital").asString());
                        }
                        
                        if (!record.get("is_high_tech").isNull()) {
                            supplier.put("isHighTech", record.get("is_high_tech").asBoolean());
                        }
                        
                        suppliers.add(supplier);
                    }
                    
                    substitute.put("suppliers", suppliers);
                    substitutesWithSuppliers.add(substitute);
                }
                
                // 3. 构建可视化所需的图数据
                String graphQuery = "MATCH (target:Product {name: $materialName}) " +
                        "MATCH (target)-[:UPSTREAM_OF]->(downstream:Product) " +
                        "WITH target, collect(downstream) AS downstream_products " +
                        "MATCH (other:Product) " +
                        "WHERE other.name IN $substituteNames " +
                        "MATCH (other)-[:UPSTREAM_OF]->(common:Product) " +
                        "WHERE common IN downstream_products " +
                        "RETURN collect(DISTINCT target) + collect(DISTINCT other) + collect(DISTINCT common) AS nodes, " +
                        "collect(DISTINCT {source: id(target), target: id(common), type: 'UPSTREAM_OF'}) + " +
                        "collect(DISTINCT {source: id(other), target: id(common), type: 'UPSTREAM_OF'}) AS relationships";
                
                // 从替代材料列表中获取所有替代品名称
                List<String> substituteNames = substitutes.stream()
                        .map(subst -> (String) subst.get("potentialSubstitute"))
                        .collect(java.util.stream.Collectors.toList());
                
                Result graphResult = tx.run(graphQuery, 
                        parameters("materialName", materialName, "substituteNames", substituteNames));
                
                List<Map<String, Object>> nodesMap = new ArrayList<>();
                List<Map<String, Object>> relationshipsMap = new ArrayList<>();
                
                if (graphResult.hasNext()) {
                    Record record = graphResult.next();
                    
                    List<Node> nodes = record.get("nodes").asList(Value::asNode);
                    
                    // 转换节点
                    for (Node node : nodes) {
                        Map<String, Object> nodeMap = convertNodeToMap(node);
                        nodesMap.add(nodeMap);
                    }
                    
                    // 转换关系
                    List<Map<String, Object>> rels = record.get("relationships").asList(Value::asMap);
                    for (Map<String, Object> rel : rels) {
                        Map<String, Object> relationship = new HashMap<>();
                        relationship.put("source", rel.get("source"));
                        relationship.put("target", rel.get("target"));
                        relationship.put("type", rel.get("type"));
                        relationshipsMap.add(relationship);
                    }
                }
                
                // 组装最终结果
                results.put("targetMaterial", materialName);
                results.put("substitutes", substitutesWithSuppliers);
                results.put("graphData", Map.of(
                    "nodes", nodesMap,
                    "relationships", relationshipsMap
                ));
                
                return results;
            });
        }
    }
}